package com.rinlink.jbcodec.transform;

import com.alibaba.fastjson.JSONObject;
import com.rinlink.jbcodec.BytesToObjectCreatorMap;
import com.rinlink.jbcodec.JSONCodec;
import com.rinlink.jbcodec.TransformCreator;
import com.rinlink.jbcodec.context.BytesToObjectCreatorContext;
import com.rinlink.jbcodec.exception.CreateTransformException;
import com.rinlink.jbcodec.exception.TransformException;

import java.nio.ByteBuffer;
import java.util.List;

public class BytesToJSON extends BytesToObject<JSONObject> {

    private BytesToObjectCreatorMap creatorMap;
    private JSONCodec.Scheme scheme;

    public BytesToJSON(ByteBuffer byteBuffer, JSONCodec.Scheme scheme, BytesToObjectCreatorMap creatorMap) {
        super(byteBuffer);
        this.scheme = scheme;
        this.creatorMap = creatorMap;
    }

    @Override
    public JSONObject transform() throws TransformException {
        JSONObject jsonData = new JSONObject();
        List<JSONCodec.Field> fields = scheme.getFields();
        int fieldSize = fields.size();
        ByteBuffer buffer = getByteBuffer();
        for (int i = 0; i < fieldSize; i++){
            JSONCodec.Field field = fields.get(i);
            TransformCreator creator = creatorMap.get(field.getType());
            BytesToObjectCreatorContext ctx = new BytesToObjectCreatorContext(scheme,buffer,jsonData);
            Transform transform = null;
            try {
                transform = creator.create(i,ctx);
            }catch (Exception e){
                RuntimeException ex =
                        new CreateTransformException(String.format("Field `%s` create transform failed, %s",field.getName(),e.getMessage()));
                ex.setStackTrace(e.getStackTrace());
                throw ex;
            }

            try {
                Object value = transform.transform();
                jsonData.put(field.getName(),value);
            }catch (Exception e){
                RuntimeException ex =
                        new TransformException(String.format("Field `%s` transform failed, %s",field.getName(),e.getMessage()));
                ex.setStackTrace(e.getStackTrace());
                throw ex;
            }
        }
        return jsonData;
    }
}
